1. /* slfrdp2r.cpp by K.Tsuru */
  2. // function ID = 2007 DRADIX, BRADIX
  3. /*******************************************************************************
  4. SLong class
  5. If m and n have a common divisor in type 2^b*R^r, they are divided by it.
  6. The results is overwritten on m and n.
  7. divisor = NULL(default)
  8. If divisor != NULL the divisor is written on it.
  9. The type of *divisor is the same as m and n.
  10. It is used in SFraction::reduce(), etc.
  11. For the SLong value(radix=DRADIX) it seems to be better to divide by the power of
  12. five, but the probability of having a large common divisor 5^q is little because
  13. it is devided by the power of DRADIX.
  14. *********************************************************************************/
  15. #ifndef SN_H
  16. #include "sn.h"
  17. #endif
  18. void ReduceByPow2Rdx(SLong& m, SLong& n, SLong* divisor){
  19. if( (m[0] & 1) || (n[0] & 1) ){ // m or n is odd.
  20. if(divisor != NULL) *divisor = 1;
  21. return;
  22. }
  23. if( m.Sign()*n.Sign() == 0){ // m == 0 || n == 0
  24. if(divisor != NULL) *divisor = 1;
  25. return;
  26. }
  27. if(m.Type() != n.Type()) m.SetError(m.RADIX_ERR,"ReduceByPow2Rdx", 2007);
  28. int cdRdxPow = (int)min(m.Tail(), n.Tail());
  29. // power of common divisor R^r
  30. if(cdRdxPow){ //devide by R^cdRdxPow
  31. m.MultPowRdx(-cdRdxPow); n.MultPowRdx(-cdRdxPow);
  32. }
  33. //It devides by a common divisor 2^n.
  34. //See also DivPow2() in gcdL().
  35. ulong cdPow2 = 0; //power of common divisor 2^n
  36. if( !(m[0] % 2u) && !(n[0] % 2u) ){ //Both are even numbers.
  37. // 16 8
  38. uint pow2 = (m.Type() == m.BIN_INT) ? (8u*sizeof(ulong)-BRADIX_BITS -1u) : 2u*DFIGURES;
  39. /*
  40. For the SLong value in order to the initial value of 'pow2' to be 16, it is necessary
  41. to judge whether have a factor 2^16 or not. To do so it needs to test lowest four
  42. figures.
  43. */
  44. ulong div = 1uL << pow2;
  45. while(div >= 2uL){
  46. while( !(m.Low2() % div) && !(n.Low2() % div) ){
  47. // m /= 2^pow2; n /= 2^pow2;
  48. LDivPow2(m, m, pow2); LDivPow2(n, n, pow2);
  49. cdPow2 += pow2;
  50. }
  51. div /= 2uL; pow2--;
  52. }
  53. }
  54. if(divisor == NULL) return;
  55. #ifndef NDEBUG
  56. assert( (m[0] & 1) || (n[0] & 1) ); // m or n is odd.
  57. assert( cdPow2 || cdRdxPow ); //It must be divisor > 1.
  58. #endif
  59. if(cdPow2){
  60. SLong two(m.Type(), m.MinSize(), 2); // = 2
  61. *divisor = Lpow(two, cdPow2); // 2^cdPow2
  62. } else {
  63. *divisor = SLong(m.Type(), m.MinSize(), 1); // = 1
  64. }
  65. if(cdRdxPow) divisor->MultPowRdx(cdRdxPow); //It multiplies by R^cdRdxPow.
  66. }

slfrdp2r.cpp : last modifiled at 2015/11/27 14:06:12(2,474 bytes)
created at 2017/10/07 10:26:50
The creation time of this html file is 2017/11/09 14:52:03 (Thu Nov 09 14:52:03 2017).